﻿using KinonekoSoftware.Studio.Utils;

namespace KinonekoSoftware.Studio.Pages.Shenanigans.Renderers
{
    public class ChannelTalkingRendererViewModel : TabViewModelCore
    {
        private readonly HashSet<string>               _MemberIDHashSet;
        private readonly Dictionary<string, Character> _MemberSet;
        private readonly TalkingEngine                 _Engine_Talking;

        private ChannelTalking _channel;
        private int            _version;


        private string     _pendingMessageContent;
        private int        _memberCount;
        private Character  _selectedCharacter;


        public ChannelTalkingRendererViewModel()
        {
            _Engine_Talking  = Platform.GetEngine<TalkingEngine>();
            _MemberSet       = new Dictionary<string, Character>();
            _MemberIDHashSet = new HashSet<string>();


            Messages                  = new ObservableCollection<TalkingMSG>();
            CapturedMessages          = new ObservableCollection<TalkingMSG>();
            CaptureThisMessageCommand = CreateCommand(DoCaptureThisMessageCommand);

            IsSingleton      = false;
            Removable        = true;
            EnableSafetyExit = true;
        }

        //-------------------------------------------------------------
        //
        //          Initializers
        //
        //-------------------------------------------------------------
        private TalkingMSG Select(TalkingObject talkingObject)
        {
            var msg = TalkingFactory.Get(talkingObject, GetOrCache);
            msg.Update(_selectedCharacter);
            return msg;
        }

        private Character GetOrCache(string actorID)
        {
            if (string.IsNullOrEmpty(actorID))
            {
                return null;
            }

            if (!_MemberSet.TryGetValue(actorID, out var character))
            {
                character = _Engine_Talking.GetCharacter(actorID);

                //
                //
                if (character is not null)
                {
                    //
                    //
                    _MemberSet.TryAdd(character.Id, character);
                }

            }

            return character;
        }

        private void AddOrSkip(Character character)
        {
            if (character is null)
            {
                return;
            }

            var id = character.Id;

            //
            // 
            if (_MemberIDHashSet.Add(id))
            {
                _MemberSet.TryAdd(id, character);
            }
        }


        //-------------------------------------------------------------
        //
        //          Override Methods
        //
        //-------------------------------------------------------------


        protected override void OnReceive(PageContext context)
        {
            if (context.Has(ContextBase.Key_Value))
            {
                _channel           = context.GetObject<ChannelTalking>(ContextBase.Key_Value);
                _selectedCharacter = context.GetObject<Character>(ContextBase.Key_Value2);
            }

            base.OnReceive(context);
        }

        protected override void OnStart()
        {
            Initialize();
            base.OnStart();
        }

        protected override void OnResume()
        {
            if (_Engine_Talking.Version != _version)
            {
                // 
                // 检测当前数据是否已经删除
                SetDeletedState(!_Engine_Talking.HasChannel(_channel.Id));

                //
                //
                Initialize();
            }


            base.OnResume();
        }


        //-------------------------------------------------------------
        //
        //          Initializers
        //
        //-------------------------------------------------------------
        #region Intialize

        private void Initialize()
        {
            Messages.Clear();


            //
            // 添加群主
            AddOrSkip(GetOrCache(_channel.OwnerID));

            //
            // 添加所有成员
            foreach (var member in _channel.Members)
            {
                AddOrSkip(GetOrCache(member));
            }


            //
            // 添加所有信息
            //
            // notice: 
            // 添加消息的时候依赖于 SelectedCharacter ，所以应该在SelectedCharacter初始化之后添加消息
            foreach (var msg in _channel.Messages
                                        .Select(Select))
            {
                //
                // add
                Messages.Add(msg);
            }


            //
            //
            Title       = $"截图：{_channel.Name}";
            MemberCount = _channel.Members.Count;
            RaiseUpdated(ChannelAvatar);
            RaiseUpdated(ChannelName);
            RaiseUpdated(ChannelIntro);
            _version = _Engine_Talking.Version;
        }


        #endregion


        //-------------------------------------------------------------
        //
        //          Command Handlers
        //
        //-------------------------------------------------------------

        private async void DoCaptureThisMessageCommand()
        {
            var count = 0;
            CapturedMessages.Clear();
            
            
            foreach (var msg in Messages)
            {
                if (count > 150)
                {
                    await Warning(TitleSR.WarningOperation, "最大允许截图的消息数量不超过150");
                    return;
                }

                if (!msg.IsSelected)
                {
                    continue;
                }
                
                //
                //
                CapturedMessages.Add(msg);
                count++;
            }
        }
        
        //-------------------------------------------------------------
        //
        //          Initializers
        //
        //-------------------------------------------------------------

        public string ChannelIntro
        {
            get => _channel?.Intro;
            set
            {
                _channel.Intro = value;
                RaiseUpdated();
                SetDirtyState(true);
            }
        }


        public string ChannelAvatar
        {
            get => _channel?.Avatar;
            set
            {
                _channel.Avatar = value;
                RaiseUpdated();
                SetDirtyState(true);
            }
        }


        public string ChannelName
        {
            get => _channel?.Name;
            set
            {
                _channel.Name = value;
                Title         = value;
                RaiseUpdated();
                SetDirtyState(true);
            }
        }

        
        public string PendingMessageContent
        {
            get => _pendingMessageContent;
            set => SetValue(ref _pendingMessageContent, value);
        }
         
        public int MemberCount
        {
            get => _memberCount;
            set => SetValue(ref _memberCount, value);
        }

        public ICommandEX CaptureThisMessageCommand { get; }

        public ObservableCollection<TalkingMSG> Messages         { get; }
        public ObservableCollection<TalkingMSG> CapturedMessages { get; }
    }
}